package com.up.gateway.filter;

import cn.hutool.core.util.StrUtil;
import com.up.tools.constants.UpConstant;
import lombok.Data;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.annotation.Order;
import org.springframework.http.HttpHeaders;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.CollectionUtils;
import org.springframework.util.PathMatcher;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;

/**
 * @author: liuchengjun
 * @title: UpGlobalFilter
 * @projectName: 海联技术中台V2.0
 * @depart 软件事业部
 * @description:
 * @date: 2023/8/31/031 14:03 (星期四)
 * @since V2.0
 */
@Component
@Order(value = Integer.MIN_VALUE)
@ConfigurationProperties(prefix = "self-config")
@Data
public class UpGlobalFilter implements GlobalFilter {
    private final Logger logger = LoggerFactory.getLogger(UpGlobalFilter.class);

    /**
     * 认证排除路径
     */
    private List<String> excludePaths;

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        ServerHttpRequest request = exchange.getRequest();
        //排除不需要校验的请求,处理请求
        if (excludeAuth(request)) {
            logger.info("当前请求:{} 将被别排除校验!", request.getPath());
            LinkedHashMap<String, Object> headerMap = new LinkedHashMap<>();
            headerMap.put(UpConstant.LOGIN_IGNORE_CHECK, true);
            logger.debug("==> headerMap:{}", headerMap);
            Consumer<HttpHeaders> httpHeaders = httpHeader -> {
                for (Map.Entry<String, Object> entry : headerMap.entrySet()) {
                    httpHeader.set(entry.getKey(), entry.getValue() + "");
                }
            };
            ServerHttpRequest nweRequest = exchange.getRequest().mutate().headers(httpHeaders).build();
            ServerWebExchange build = exchange.mutate().request(nweRequest).build();
            return chain.filter(build);
        }
        //移交给下个过滤器
        return chain.filter(exchange);
    }
    private boolean excludeAuth(ServerHttpRequest request) {
        String first = request.getHeaders().getFirst(UpConstant.LOGIN_IGNORE_CHECK);
        if(StrUtil.isNotEmpty(first) && Boolean.valueOf(first)){
            return true;
        }
        logger.debug("==> authExcludePath:{}", excludePaths);
        if (!CollectionUtils.isEmpty(excludePaths)) {
            PathMatcher pathMatcher = new AntPathMatcher();
            for (String excludePath : excludePaths) {
                if (pathMatcher.match(excludePath, request.getURI().getPath())) {
                    return true;
                }
            }
        }
        return false;
    }
}
